<template>
  <el-dialog
    v-model="dialogVisible"
    title="批量设备二维码预览"
    width="90%"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    class="batch-qrcode-dialog"
  >
    <!-- 控制面板 -->
    <div class="control-panel">
      <el-form :model="config" label-width="100px" inline>
        <el-form-item label="二维码大小">
          <el-select v-model="config.qrCodeSize" style="width: 120px">
            <el-option label="小 (120px)" :value="120" />
            <el-option label="中 (160px)" :value="160" />
            <el-option label="大 (200px)" :value="200" />
            <el-option label="超大 (240px)" :value="240" />
          </el-select>
        </el-form-item>
        <el-form-item label="每行显示">
          <el-select v-model="config.columns" style="width: 120px">
            <el-option label="2列" :value="2" />
            <el-option label="3列" :value="3" />
            <el-option label="4列" :value="4" />
            <el-option label="5列" :value="5" />
          </el-select>
        </el-form-item>
      </el-form>
    </div>

    <!-- 二维码预览区域 -->
    <div class="qrcode-preview-container">
      <div v-if="loading" class="loading-container">
        <el-skeleton animated :rows="10" />
      </div>

      <div v-else-if="error" class="error-container">
        <el-empty description="加载失败" />
        <el-button type="primary" @click="retryLoad">重试</el-button>
      </div>

      <div v-else class="qrcode-grid" :style="gridStyle">
        <div v-for="item in qrCodeList" :key="item.deviceId" class="qrcode-item" :style="itemStyle">
          <div class="qrcode-card">
            <!-- 设备名称 -->
            <div class="qrcode-header">
              <h3>{{ item.deviceName || '设备二维码' }}</h3>
              <p class="device-id">{{ item.deviceKey }}</p>
            </div>

            <!-- 二维码图片 -->
            <div class="qrcode-image">
              <img
                :src="item.qrCode"
                :alt="item.deviceName"
                :style="qrCodeImageStyle"
                @error="handleImageError"
              />
            </div>

            <!-- 设备信息 -->
            <div class="qrcode-info">
              <p class="device-type">设备类型: {{ getDeviceTypeName(item.deviceType) }}</p>
            </div>
          </div>
        </div>
      </div>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="closeDialog">关闭</el-button>
        <el-button type="primary" @click="handleExportExcel" :disabled="!qrCodeList.length">
          <Icon icon="ep:document" class="mr-5px" /> 导出Excel
        </el-button>
        <el-button type="success" @click="handleExportPDF" :disabled="!qrCodeList.length">
          <Icon icon="ep:document" class="mr-5px" /> 导出PDF
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import { DeviceApi, DeviceVO, BatchQRCodeResponse } from '@/api/mqtt/device'
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { ElMessage } from 'element-plus'
import * as XLSX from 'xlsx'

// 定义接口
interface QRCodeItem {
  deviceId: number
  deviceName: string
  deviceKey: string
  deviceType: number
  address: string
  qrCode: string
  success: boolean
  error?: string
}

// 响应式变量
const dialogVisible = ref(false)
const loading = ref(false)
const error = ref(false)
const qrCodeList = ref<QRCodeItem[]>([])

// 配置选项
const config = ref({
  qrCodeSize: 160,
  columns: 3
})

// 计算样式
const gridStyle = computed(() => ({
  display: 'grid',
  gridTemplateColumns: `repeat(${config.value.columns}, 1fr)`,
  gap: '20px',
  padding: '20px'
}))

const itemStyle = computed(() => ({
  display: 'flex',
  justifyContent: 'center'
}))

const qrCodeImageStyle = computed(() => ({
  width: config.value.qrCodeSize + 'px',
  height: config.value.qrCodeSize + 'px',
  objectFit: 'contain' as const,
  display: 'block',
  backgroundColor: '#ffffff',
  border: '1px solid #f0f0f0',
  borderRadius: '4px',
  boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)'
}))

// 处理字符编码问题，修复乱码
const fixEncoding = (text: string): string => {
  if (!text) return text

  // 检查是否包含乱码字符
  const garbledPattern =
    /[^\x00-\x7F\u4e00-\u9fff\u3400-\u4dbf\u20000-\u2a6df\u2a700-\u2b73f\u2b740-\u2b81f\u2b820-\u2ceaf\uf900-\ufaff\u3300-\u33ff\ufe30-\ufe4f\u3000-\u303f\uff00-\uffef]/

  if (!garbledPattern.test(text)) {
    return text
  }

  // 尝试修复特定的乱码模式
  const specificGarbledPatterns = [
    { pattern: /\\\e°gQY\\ •êq6gQO>l4zÙ/g, replacement: '小将新村外小将自然村供水站' },
    { pattern: /SÅepmK‹Õ^sSõ/g, replacement: '参数测试平台' },
    { pattern: /e'lÉgQOxI4zÙ/g, replacement: '南洲供水站' },
    { pattern: /SWm2O>I4zÙ/g, replacement: '里遁山村燕窠自然村供水站' },
    { pattern: /G M%Y/g, replacement: 'GM设备' }
  ]

  for (const { pattern, replacement } of specificGarbledPatterns) {
    if (pattern.test(text)) {
      return text.replace(pattern, replacement)
    }
  }

  // 清理乱码字符
  return text.replace(garbledPattern, '')
}

// 获取设备类型名称
const getDeviceTypeName = (deviceType: number) => {
  const dictOptions = getIntDictOptions(DICT_TYPE.MQTT_DEVICE_TYPE)
  const option = dictOptions.find((item) => item.value === deviceType)
  return option ? option.label : '未知类型'
}

// 存储设备数据
const deviceList = ref<DeviceVO[]>([])

// 打开对话框
const open = async (devices: DeviceVO[]) => {
  dialogVisible.value = true
  deviceList.value = devices
  await loadAllQRCodes(devices)
}

// 重试加载
const retryLoad = async () => {
  if (deviceList.value.length > 0) {
    await loadAllQRCodes(deviceList.value)
  }
}

// 加载所有二维码 - 使用批量接口
const loadAllQRCodes = async (devices?: DeviceVO[]) => {
  if (!devices || devices.length === 0) return

  loading.value = true
  error.value = false
  qrCodeList.value = []

  try {
    // 提取所有设备ID
    const deviceIds = devices.map(device => device.id)
    
    // 批量获取二维码
    const qrCodeDataList = await DeviceApi.getDeviceQRCodeBase64Batch(deviceIds)
    
    // 创建设备ID到二维码数据的映射
    const qrCodeMap = new Map<number, BatchQRCodeResponse>()
    qrCodeDataList.forEach(item => {
      qrCodeMap.set(item.deviceId, item)
    })
    
    // 构建结果列表
    const results = devices.map(device => {
      const qrCodeData = qrCodeMap.get(device.id)
      
      if (qrCodeData) {
        return {
          deviceId: device.id,
          deviceName: fixEncoding(device.deviceName),
          deviceKey: fixEncoding(device.deviceKey),
          deviceType: device.deviceType,
          address: fixEncoding(device.address),
          qrCode: qrCodeData.qrcode,
          success: true
        } as QRCodeItem
      } else {
        return {
          deviceId: device.id,
          deviceName: fixEncoding(device.deviceName),
          deviceKey: fixEncoding(device.deviceKey),
          deviceType: device.deviceType,
          address: fixEncoding(device.address),
          qrCode: '',
          success: false,
          error: '获取二维码失败'
        } as QRCodeItem
      }
    })
    
    qrCodeList.value = results

    const successCount = results.filter((r) => r.success).length
    const failCount = results.filter((r) => !r.success).length

    if (failCount > 0) {
      ElMessage.warning(`成功加载 ${successCount} 个，失败 ${failCount} 个设备二维码`)
    } else {
      ElMessage.success(`成功加载 ${successCount} 个设备二维码`)
    }
  } catch (err: any) {
    error.value = true
    ElMessage.error('批量加载二维码失败')
    console.error('批量加载二维码失败:', err)
  } finally {
    loading.value = false
  }
}

// 关闭对话框
const closeDialog = () => {
  dialogVisible.value = false
  qrCodeList.value = []
}

// 导出Excel (使用xlsx库)
const handleExportExcel = async () => {
  try {
    // 准备数据
    const data = qrCodeList.value.map((item) => ({
      设备ID: item.deviceId,
      设备名称: item.deviceName,
      设备标识: item.deviceKey,
      设备类型: getDeviceTypeName(item.deviceType),
      设备地址: item.address || '未设置',
      状态: item.success ? '成功' : '失败',
      错误信息: item.error || ''
    }))

    // 创建工作簿
    const workbook = XLSX.utils.book_new()
    const worksheet = XLSX.utils.json_to_sheet(data)

    // 设置列宽
    const columnWidths = [
      { wch: 10 }, // 设备ID
      { wch: 20 }, // 设备名称
      { wch: 25 }, // 设备标识
      { wch: 15 }, // 设备类型
      { wch: 30 }, // 设备地址
      { wch: 10 }, // 状态
      { wch: 20 } // 错误信息
    ]
    worksheet['!cols'] = columnWidths

    // 添加工作表到工作簿
    XLSX.utils.book_append_sheet(workbook, worksheet, '设备二维码')

    // 生成文件名
    const fileName = `设备二维码_${new Date().toISOString().slice(0, 10)}.xlsx`

    // 导出文件
    XLSX.writeFile(workbook, fileName)

    ElMessage.success('Excel导出成功')
  } catch (err: any) {
    ElMessage.error('导出失败')
    console.error('导出失败:', err)
  }
}

// 导出PDF - 使用浏览器打印功能
const handleExportPDF = () => {
  try {
    ElMessage.info('正在生成PDF，请稍候...')

    // 创建打印窗口
    const printWindow = window.open('', '_blank')
    if (!printWindow) {
      ElMessage.error('无法打开打印窗口，请检查浏览器弹窗设置')
      return
    }

    // 生成打印内容
    const styleContent =
      'body { font-family: SimSun, STSong, serif; margin: 0; padding: 20px; background: white; }' +
      '.qrcode-container { display: flex; flex-wrap: wrap; gap: 15px; justify-content: flex-start; }' +
      '.qrcode-card { background: white; border: 1px solid #e4e7ed; border-radius: 12px; padding: 20px; text-align: center; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); width: ' +
      (config.value.qrCodeSize + 40) +
      'px; display: inline-block; margin: 8px; vertical-align: top; box-sizing: border-box; page-break-inside: avoid; }' +
      '.device-name { font-size: 16px; font-weight: 600; color: #333; margin-bottom: 10px; word-break: break-all; line-height: 1.2; }' +
      '.device-key { font-size: 13px; color: #666; margin-bottom: 15px; word-break: break-all; line-height: 1.2; font-family: "Courier New", monospace; }' +
      '.qrcode-image { width: ' +
      config.value.qrCodeSize +
      'px; height: ' +
      config.value.qrCodeSize +
      'px; object-fit: contain; display: block; margin: 0 auto; background: #ffffff; border: 1px solid #f0f0f0; border-radius: 6px; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); }' +
      '.device-type { font-size: 13px; color: #666; margin-top: 12px; font-weight: 500; }' +
      '@media print { body { margin: 0; } .qrcode-card { page-break-inside: avoid; break-inside: avoid; } }'

    // 生成HTML内容
    let htmlContent = '<div class="qrcode-container">'
    qrCodeList.value.forEach((item) => {
      const deviceName = fixEncoding(item.deviceName) || '设备二维码'
      const deviceKey = fixEncoding(item.deviceKey) || ''
      const deviceType = getDeviceTypeName(item.deviceType) || '未知类型'

      htmlContent += '<div class="qrcode-card">'
      htmlContent += '<div class="device-name">' + deviceName + '</div>'
      htmlContent += '<div class="device-key">' + deviceKey + '</div>'
      htmlContent +=
        '<img src="' + item.qrCode + '" class="qrcode-image" alt="' + deviceName + '" />'
      htmlContent += '<div class="device-type">设备类型: ' + deviceType + '</div>'
      htmlContent += '</div>'
    })
    htmlContent += '</div>'

    // 完整的HTML文档 - 使用函数避免Vue模板解析问题
    const createHTMLContent = () => {
      return (
        '<!DOCTYPE html>' +
        '<html>' +
        '<head>' +
        '<title>设备二维码</title>' +
        '<style>' +
        styleContent +
        '</style>' +
        '</head>' +
        '<body>' +
        htmlContent +
        '<script>' +
        'window.onload = function() {' +
        '  setTimeout(function() {' +
        '    window.print();' +
        '    window.close();' +
        '  }, 500);' +
        '};' +
        '<\/script>' +
        '</body>' +
        '</html>'
      )
    }

    const fullContent = createHTMLContent()

    // 写入内容并打印
    printWindow.document.write(fullContent)
    printWindow.document.close()

    ElMessage.success('已打开打印窗口，请选择"另存为PDF"')
  } catch (err: any) {
    ElMessage.error('PDF导出失败: ' + err.message)
    console.error('PDF导出失败:', err)
  }
}

// 处理图片加载错误
const handleImageError = (event: Event) => {
  const img = event.target as HTMLImageElement
  // 设置默认的占位符图片或隐藏图片
  img.style.display = 'none'
  console.warn('二维码图片加载失败:', img.src)
}

// 暴露方法
defineExpose({
  open
})
</script>

<style scoped>
.batch-qrcode-dialog {
  max-height: 90vh;
}

.control-panel {
  background: #f5f5f5;
  padding: 16px;
  border-radius: 8px;
  margin-bottom: 16px;
}

.qrcode-preview-container {
  max-height: 60vh;
  overflow-y: auto;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
}

.qrcode-grid {
  padding: 20px;
}

.qrcode-item {
  display: flex;
  justify-content: center;
  align-items: stretch;
  margin-bottom: 20px;
}

.qrcode-card {
  background: white;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  padding: 16px;
  text-align: center;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  min-width: 200px;
  max-width: 280px;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.qrcode-header h3 {
  margin: 0 0 8px 0;
  color: #333;
  font-size: 18px;
}

.qrcode-image {
  margin: 12px 0;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: auto;
}

.qrcode-image img {
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  object-fit: contain;
  max-width: 100%;
  height: auto;
  display: block;
  background-color: #ffffff;
  border: 1px solid #f0f0f0;
}

.qrcode-info {
  font-size: 12px;
  color: #606266;
  line-height: 1.4;
  width: 100%;
  margin-top: 8px;
}

.qrcode-info p {
  margin: 4px 0;
  word-break: break-all;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.loading-container {
  padding: 40px;
  text-align: center;
}

.error-container {
  padding: 40px;
  text-align: center;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}
</style>